package club.zhilin.guli.service.trade.controller.portal;

import club.zhilin.guli.common.base.result.CommonResult;
import club.zhilin.guli.common.base.util.StreamUtils;
import club.zhilin.guli.service.base.constant.GlobalConstant;
import club.zhilin.guli.service.trade.domain.Order;
import club.zhilin.guli.service.trade.prop.WeiXinPayProperties;
import club.zhilin.guli.service.trade.service.IOrderService;
import club.zhilin.guli.service.trade.service.IWeiXinPayService;
import com.github.wxpay.sdk.WXPayUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zhilin
 * @since 2022/3/4 16:39
 */
@Slf4j
@RestController
@Api(tags = "网站微信支付")
@RequestMapping("/portal/trade/pay")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class PortalWeiXinPayController {

    private final IWeiXinPayService iWeiXinPayService;
    private final WeiXinPayProperties weiXinPayProperties;
    private final IOrderService iOrderService;

    @ApiOperation("统一下单接口调用")
    @GetMapping("/createNative/{orderNo}")
    public CommonResult<Map<String, Object>> createNative(@PathVariable String orderNo, HttpServletRequest request) {
        String remoteAddr = request.getRemoteAddr();
        Map<String, Object> map = iWeiXinPayService.createNative(orderNo, remoteAddr);
        return CommonResult.success(map);
    }

    @ApiOperation("微信支付回调方法")
    @PostMapping("/callback")
    @SuppressWarnings({"all"})
    public String notify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String notify = StreamUtils.inputStream2String(request.getInputStream(), "utf-8");
        if (WXPayUtil.isSignatureValid(notify, weiXinPayProperties.getPartnerKey())) {
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(notify);
            // 判断返回是否正确
            if (GlobalConstant.SUCCESS.equals(notifyMap.get("result_code"))) {
                // 校验金额
                Order order = iOrderService.getOrderByOrderNo(notifyMap.get("out_trade_no"));
                if (order != null && order.getTotalFee().intValue() == Integer.parseInt(notifyMap.get("total_fee"))) {
                    // 接口的幂等性:无论接口调用多少次,最后所影响的结果都是一致的 如果此处订单状态已经进行被修改过则不进行修改订单
                    if (order.getStatus()) {
                        Map<String, String> result = new HashMap<>(2);
                        result.put("return_code", GlobalConstant.SUCCESS);
                        result.put("result_msg", "已完成支付");
                        String xml = WXPayUtil.mapToXml(result);
                        response.setContentType("text/xml");
                        return xml;
                    }
                    // 支付成功
                    iOrderService.updateOrderStatus(notifyMap);
                    Map<String, String> result = new HashMap<>(2);
                    result.put("return_code", GlobalConstant.SUCCESS);
                    result.put("result_msg", "已完成支付");
                    String xml = WXPayUtil.mapToXml(result);
                    response.setContentType("text/xml");
                    return xml;
                }
            }
        }
        // 创建响应对象,微信接收到的校验失败的结果后,会反复的调用当前回调函数
        Map<String, String> result = new HashMap<>(2);
        result.put("return_code", GlobalConstant.FAIL);
        result.put("result_msg", "");
        String xml = WXPayUtil.mapToXml(result);
        response.setContentType("text/xml");
        return xml;
    }


}
